import 'dart:convert';
import 'dart:math';

import 'package:ai_report/ai_report.dart';

import 'data/ai_report_step.dart';
import 'data/balance_score.dart';
import 'data/level.dart';

List<BalanceScore> scoreList = List.empty(growable: true);
List<Level> levelList = List.empty(growable: true);

/// 平衡系数
final balanceCoefficients = [9.22, 58.45, 20.36, 13.72, 6.82, 6.84];

const String fileBalanceScore = 'packages/ai_report/assets/balance_score.json';
const String fileLevel = 'packages/ai_report/assets/level.json';

/// originalScore-原始分  standardScore-标准分  realScore-实际目差  balanceScore-平衡目差  balanceCoefficient-平衡系数
double amendScore(double originalScore, double realScore, int stage) {
  Map<double, double> map = {};
  for (var element in scoreList) {
    switch (stage) {
      case 0:
        map[element.overall!] = element.overAllRs!;
        break;
      case 1:
        map[element.opening!] = element.openingRs!;
        break;
      case 2:
        map[element.earlyMiddleGame!] = element.earlyMiddleGamers!;
        break;
      case 3:
        map[element.middleGame!] = element.middleGamers!;
        break;
      case 4:
        map[element.lateMiddleGame!] = element.lateMiddleGamers!;
        break;
      case 5:
        map[element.endgame!] = element.endGamers!;
        break;
    }
  }
  double standardScore = 0;
  int index = isWithinInterval(realScore, map);
  standardScore = map.values.toList()[index];
  double balanceScore = map.keys.toList()[index];
  double balanceCoefficient = balanceCoefficients[stage];
  var result = (originalScore * 0.2 + standardScore * 0.8) +
      (realScore - balanceScore) * balanceCoefficient;
  double score = double.parse(result.toStringAsFixed(2));
  if (score < 1) {
    score = 1;
  }
  if (score > 119) {
    score = 119;
  }
  return score;
}

/// 二次校对总分
double secondAmendScore(int count) {
  return double.parse(
      (0.2 * (count - 12) * cos((pi / 48) * count)).toStringAsFixed(2));
}

getScoreList() async {
  if (scoreList.isEmpty) {
    var content = await loadAsset(fileBalanceScore);
    List<dynamic> scores =
        json.decode(content).map((e) => BalanceScore.fromJson(e)).toList();
    scoreList = List<BalanceScore>.from(scores);
  }

  if (levelList.isEmpty) {
    var levelContent = await loadAsset(fileLevel);
    List<dynamic> levels =
        json.decode(levelContent).map((e) => Level.fromJson(e)).toList();
    levelList = List<Level>.from(levels);
  }
}

String calculateLevel(double score, int stage) {
  Map<String, double> map = {};
  for (var element in levelList) {
    switch (stage) {
      case 0:
        map[element.level!] = element.global!;
        break;
      case 1:
        map[element.level!] = element.layout!;
        break;
      case 2:
        map[element.level!] = element.middleFront!;
        break;
      case 3:
        map[element.level!] = element.middle!;
        break;
      case 4:
        map[element.level!] = element.middleBack!;
        break;
      case 5:
        map[element.level!] = element.endGame!;
        break;
    }
  }
  String level = map.keys.toList()[isWithinIntervalLevel(score, map)];
  return level;
}

int isWithinInterval(double value, Map<double, double> intervals) {
  var keyList = intervals.keys.toList();
  for (int i = 0; i < keyList.length; i++) {
    if (i < keyList.length - 1) {
      if (value >= keyList[i] && value < keyList[i + 1]) {
        return i;
      }
    } else {
      if (value >= keyList[i]) {
        return i;
      }
    }
  }
  return 0;
}

int isWithinIntervalLevel(double value, Map<String, double> intervals) {
  var valueList = intervals.values.toList();
  for (int i = 0; i < valueList.length; i++) {
    if (i < valueList.length - 1) {
      if (value >= valueList[i] && value < valueList[i + 1]) {
        return i;
      }
    } else {
      if (value >= valueList[i]) {
        return i;
      }
    }
  }
  return 0;
}

List<AIReportStep> calculateHighlightInfoPlus(List<AIReportStep> stepList) {
  final List<AIReportStep> goodList = [];
  final List<AIReportStep> openingList = [];
  final List<AIReportStep> earlyMiddleGameList = [];
  final List<AIReportStep> middleGameList = [];
  final List<AIReportStep> lateMiddleGameList = [];
  final List<AIReportStep> endGameList = [];

  // 分类逻辑
  for (final element in stepList) {
    final position = element.cm;
    final recommend = element.rc;
    final num = element.num!;

    if (position == recommend) {
      switch (chessStage(num)) {
        case ChessStage.opening:
          openingList.add(element);
          break;
        case ChessStage.early_middle_game:
          earlyMiddleGameList.add(element);
          break;
        case ChessStage.middle_game:
          middleGameList.add(element);
          break;
        case ChessStage.late_middle_game:
          lateMiddleGameList.add(element);
          break;
        case ChessStage.endgame:
          endGameList.add(element);
          break;
      }
    }
  }

  void bestChess(List<AIReportStep> list) {
    if (list.isNotEmpty) {
      list.sort((a, b) => a.p!.compareTo(b.p!));
      goodList.add(list.first);
    }
  }

  // 处理各阶段最佳着法
  bestChess(openingList);
  bestChess(earlyMiddleGameList);
  bestChess(middleGameList);
  bestChess(lateMiddleGameList);
  bestChess(endGameList);

  return goodList;
}
